package com.lehecai.ucenter.action.user;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.lehecai.ucenter.action.BaseAction;
import com.lehecai.ucenter.constant.AuthorizeStatus;
import com.lehecai.ucenter.constant.FormatType;
import com.lehecai.ucenter.entity.permission.User;
import com.lehecai.ucenter.service.permission.UserService;


public class IpAuthorizeAction extends BaseAction {

	private UserService userService;

    private static final String JSON_CODE = "code";
    private static final String JSON_MESSAGE = "message";
    private static final String JSON_DATA = "data";
    private static final String JSON_DATA_APP = "app";
    private static final String JSON_DATA_USERNAME = "username";
    private static final String JSON_DATA_CLIENT_IP = "client_ip";
    private static final String JSON_DATA_RESOURCE_IP = "resource_ip";
    private static final String JSON_DATA_FORMAT = "format";

    private String app;
	private String username;
	private String clientIp;
	private String resourceIp;
    private String format;

	public String handle() {
        HttpServletResponse response = ServletActionContext.getResponse();
        JSONObject jsonObject = new JSONObject();

        JSONObject jsonDataObject = new JSONObject();

        logger.info("进入验证ip授权");
        if (StringUtils.isEmpty(format)) {
            format = FormatType.FORMAT_TYPE_RAW.getKey();
        }
        FormatType formatType = FormatType.getByKey(format);
        if (StringUtils.isEmpty(app)) {
            logger.error("应用名称为空");
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE_APP_NOT_NULL));
            return null;
        }
		if (StringUtils.isEmpty(username)) {
			logger.error("用户名为空");
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE_USERNAME_NOT_NULL));
			return null;
		}
		if (StringUtils.isEmpty(clientIp)) {
			logger.error("用户ip为空");
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE_CLIENT_IP_NOT_NULL));
			return null;
		}
        if (StringUtils.isEmpty(resourceIp)) {
			logger.error("资源ip为空");
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE_RESOURCE_IP_NOT_NULL));
			return null;
		}
        logger.info("验证ip授权通过参数完整性验证，参数包括:app={}, username={}, clientIp={}, resourceIp={}, format={}", new Object[]{app, username, clientIp, resourceIp, format});

        User user = userService.findByUsername(username);
		if (user == null) {
			logger.error("用户不存在:{}", username);
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE));
            return null;
		}

        if (StringUtils.isEmpty(user.getClientIp())) {
            logger.error("用户ip未设定，授权验证失败:username={}", username);
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE));
            return null;
        }

        boolean matchClientIp = false;
        try {
            matchClientIp = matchIp(user.getClientIp(), clientIp);
        } catch (Exception e) {
            logger.error("匹配用户ip与设定好的用户ip格式时错误，restrictionIp={}, clientIp={}", new Object[]{user.getClientIp(), clientIp});
            logger.error(e.getMessage(), e);
        }

        if (!matchClientIp) {
            logger.error("用户ip不匹配，授权验证失败:username={}", username);
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE));
            return null;
        }

        if (StringUtils.isEmpty(user.getResourceIp())) {
            logger.error("资源ip未设定，授权验证失败:username={}", username);
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE));
            return null;
        }

        boolean matchSourceIp = false;
        try {
            matchSourceIp = matchIp(user.getResourceIp(), resourceIp);
        } catch (Exception e) {
            logger.error("匹配资源ip与设定好的资源ip格式时错误，restrictionIp={}, source={}", new Object[]{user.getResourceIp(), resourceIp});
            logger.error(e.getMessage(), e);
        }

        if (!matchSourceIp) {
            logger.error("用户ip不匹配，授权验证失败:username={}", username);
            super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_FAILURE));
            return null;
        }

        logger.info("用户ip授权通过！username={}, client_ip={}, source_ip={}", new Object[]{username, user.getClientIp(), user.getResourceIp()});
        super.writeRs(response, this.generateResponseResult(formatType, AuthorizeStatus.AUTHORIZE_STATUS_SUCCESS));

		logger.info("用户ip授权结束");
		return null;
	}

    //ip段匹配
    private boolean matchIp(String restrictionIp, String remoteIp) {
        //有效ip段或请求ip不存在
        if (restrictionIp == null || remoteIp == null) {
            return false;
        }

        if ("*".equals(restrictionIp)) {
            return true;
        }

        String[] restrictionIpArray = restrictionIp.trim().split(",");
        String[] remoteIpItem = remoteIp.trim().split("\\.");
        if (restrictionIpArray.length > 0) {
            for (String restrictionIpSegment : restrictionIpArray) {
                String[] restrictionIpItem = restrictionIpSegment.trim().split("\\.");
                if (restrictionIpItem.length == 4 && remoteIpItem.length == 4) {
                    boolean flag = true;
                    for (int i = 0; i < 4; i++) {
                        if (!restrictionIpItem[i].equals("*") && !restrictionIpItem[i].equals(remoteIpItem[i])) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    private String generateResponseResult(FormatType formatType, AuthorizeStatus authorizeStatus) {
        String result = null;
        if (formatType.getCode() == FormatType.FORMAT_TYPE_RAW.getCode()) {
            StringBuffer sb = new StringBuffer();
            sb.append(JSON_CODE).append("=").append(authorizeStatus.getCode());
            sb.append("&");
            sb.append(JSON_MESSAGE).append("=").append(authorizeStatus.getMessage());
            if (!StringUtils.isEmpty(app)) {
                sb.append("&");
                sb.append(JSON_DATA).append(".").append(JSON_DATA_APP).append("=").append(app);
            }
            if (!StringUtils.isEmpty(username)) {
                sb.append("&");
                sb.append(JSON_DATA).append(".").append(JSON_DATA_USERNAME).append("=").append(username);
            }
            if (!StringUtils.isEmpty(clientIp)) {
                sb.append("&");
                sb.append(JSON_DATA).append(".").append(JSON_DATA_CLIENT_IP).append("=").append(clientIp);
            }
            if (!StringUtils.isEmpty(resourceIp)) {
                sb.append("&");
                sb.append(JSON_DATA).append(".").append(JSON_DATA_RESOURCE_IP).append("=").append(resourceIp);
            }
            if (!StringUtils.isEmpty(format)) {
                sb.append("&");
                sb.append(JSON_DATA).append(".").append(JSON_DATA_FORMAT).append("=").append(format);
            }
            result = sb.toString();
        } else if (formatType.getCode() == FormatType.FORMAT_TYPE_JSON.getCode()) {
            JSONObject jsonObject = new JSONObject();
            JSONObject jsonDataObject = new JSONObject();

            jsonObject.put(JSON_CODE, authorizeStatus.getCode());
            jsonObject.put(JSON_MESSAGE, authorizeStatus.getMessage());
            jsonDataObject.put(JSON_DATA_APP, app);
            jsonDataObject.put(JSON_DATA_USERNAME, username);
            jsonDataObject.put(JSON_DATA_CLIENT_IP, clientIp);
            jsonDataObject.put(JSON_DATA_RESOURCE_IP, resourceIp);
            jsonDataObject.put(JSON_DATA_FORMAT, format);
            jsonObject.put(JSON_DATA, jsonDataObject);
            result = jsonObject.toString();
        }
        return result;
    }

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getClientIp() {
        return clientIp;
    }

    public void setClientIp(String clientIp) {
        this.clientIp = clientIp;
    }

    public String getResourceIp() {
        return resourceIp;
    }

    public void setResourceIp(String resourceIp) {
        this.resourceIp = resourceIp;
    }

    public String getApp() {
        return app;
    }

    public void setApp(String app) {
        this.app = app;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }
}
